package branch.feature.gaode_map.switch_map

import android.Manifest
import android.animation.Animator
import android.animation.AnimatorListenerAdapter
import android.app.Activity
import android.content.pm.PackageManager
import android.os.Bundle
import android.os.Handler
import android.util.Log
import android.view.View
import android.widget.Button
import android.widget.CompoundButton
import android.widget.LinearLayout
import android.widget.Toast
import android.widget.ToggleButton
import androidx.annotation.NonNull
import androidx.appcompat.app.AlertDialog
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import com.amap.api.location.AMapLocation
import com.amap.api.location.AMapLocationClient
import com.amap.api.location.AMapLocationClientOption
import com.amap.api.location.AMapLocationListener
import com.amap.api.maps.AMap
import com.amap.api.maps.AMapOptions
import com.amap.api.maps.CameraUpdateFactory
import com.amap.api.maps.MapsInitializer
import com.amap.api.maps.TextureMapView
import com.amap.api.maps.model.LatLng
import com.example.myapplication.R
import com.google.android.gms.common.ConnectionResult
import com.google.android.gms.common.GooglePlayServicesUtil
import com.google.android.gms.maps.GoogleMap
import com.google.android.gms.maps.GoogleMapOptions
import com.google.android.gms.maps.MapView
import com.google.android.gms.maps.OnMapReadyCallback
import com.google.android.gms.maps.model.CameraPosition
import com.google.android.gms.maps.model.LatLng as GoogleLatLng

class MainActivitykt : Activity(), View.OnClickListener, AMap.OnCameraChangeListener,
    OnMapReadyCallback, GoogleMap.OnCameraMoveListener, AMapLocationListener,
    CompoundButton.OnCheckedChangeListener {

    private lateinit var mCheckBtn: ToggleButton
    private lateinit var mapBtn: Button
    private lateinit var mAmapView: TextureMapView
    private lateinit var mGoogleMapView: MapView
    private var zoom = 10f
    private var latitude = 39.23242
    private var longitude = 116.253654
    private var mIsAmapDisplay = true
    private var mIsAuto = true
    private lateinit var mLocationClient: AMapLocationClient
    private lateinit var mLocationOption: AMapLocationClientOption
    private var googleMap: GoogleMap? = null
    private var aMap: AMap? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_switch_map_gd)
        // 高德隐私合规
        run {
            MapsInitializer.updatePrivacyShow(this, true, true)
            MapsInitializer.updatePrivacyAgree(this, true)
            AMapLocationClient.updatePrivacyAgree(this, true)
            AMapLocationClient.updatePrivacyShow(this, true, true)
        }

        requestLocationPermission()
        init()
        initLocation()
        mAmapView = TextureMapView(this).apply {
            layoutParams = LinearLayout.LayoutParams(
                LinearLayout.LayoutParams.MATCH_PARENT,
                LinearLayout.LayoutParams.MATCH_PARENT
            )
        }
        findViewById<LinearLayout>(R.id.map_container).addView(mAmapView)
        mAmapView.onCreate(savedInstanceState)
        mAmapView.getMap().setOnCameraChangeListener(this)
    }

    private fun init() {
        mCheckBtn = findViewById(R.id.auto)
        mapBtn = findViewById(R.id.button)
        mapBtn.setOnClickListener(this)
        mCheckBtn.setOnCheckedChangeListener(this)
    }

    private fun initLocation() {
        mLocationClient = AMapLocationClient(applicationContext).apply {
            setLocationListener(this@MainActivitykt)
        }
        mLocationOption = AMapLocationClientOption().apply {
            setLocationMode(AMapLocationClientOption.AMapLocationMode.Hight_Accuracy)
            setOnceLocation(true)
        }
        mLocationClient.setLocationOption(mLocationOption)
        mLocationClient.startLocation()
    }

    override fun onClick(v: View) {
        when (v.id) {
            R.id.auto -> mIsAuto = mCheckBtn.isChecked
            R.id.button -> {
                mCheckBtn.isChecked = false
                mIsAuto = false
                if (mIsAmapDisplay) changeToGoogleMapView() else changeToAmapView()
            }
        }
    }

    private fun changeToAmapView() {
        if (googleMap != null && googleMap!!.cameraPosition != null) {
            zoom = googleMap!!.cameraPosition.zoom
            latitude = googleMap!!.cameraPosition.target.latitude
            longitude = googleMap!!.cameraPosition.target.longitude
        }
        mAmapView = TextureMapView(this, AMapOptions().apply {
            camera(
                com.amap.api.maps.model.CameraPosition(
                    LatLng(latitude, longitude), zoom, 0f, 0f
                )
            )
        })
        mAmapView.onCreate(null)
        mAmapView.onResume()
        findViewById<LinearLayout>(R.id.map_container).addView(mAmapView)
        mGoogleMapView.animate().alpha(0f).setDuration(500)
            .setListener(object : AnimatorListenerAdapter() {
                override fun onAnimationEnd(animation: Animator) {
                    mGoogleMapView.visibility = View.GONE
                    findViewById<LinearLayout>(R.id.map_container).removeView(mGoogleMapView)
                    mGoogleMapView.onDestroy()
                }
            })
        mAmapView.getMap().setOnCameraChangeListener(this)
        mIsAmapDisplay = true
        mapBtn.text = "To Google"
    }

    private fun changeToGoogleMapView() {
        if (!checkGooglePlayServices()) return
        // ERROR: aMap!!为null
//        zoom = aMap!!.cameraPosition.zoom
//        latitude = aMap!!.cameraPosition.target.latitude
//        longitude = aMap!!.cameraPosition.target.longitude
        mapBtn.text = "To Amap"
        mIsAmapDisplay = false
        mGoogleMapView = MapView(this, GoogleMapOptions().apply {
            camera(
                CameraPosition(
                    GoogleLatLng(latitude, longitude), zoom, 0f, 0f
                )
            )
        })
        mGoogleMapView.onCreate(null)
        mGoogleMapView.onResume()
        findViewById<LinearLayout>(R.id.map_container).addView(mGoogleMapView)
        mGoogleMapView.getMapAsync(this)
        Handler().postDelayed({ mAmapView.onDestroy() }, 500)
    }

    override fun onCameraChange(cameraPosition: com.amap.api.maps.model.CameraPosition) {}

    override fun onCameraChangeFinish(cameraPosition: com.amap.api.maps.model.CameraPosition) {
        longitude = cameraPosition.target.longitude
        latitude = cameraPosition.target.latitude
        zoom = cameraPosition.zoom
        if (!isInArea(latitude, longitude) && mIsAmapDisplay && mIsAuto) {
            changeToGoogleMapView()
        }
    }

    private fun isInArea(latitude: Double, longitude: Double): Boolean {
        return latitude > 3.837031 && latitude < 53.563624 &&
                longitude < 135.095670 && longitude > 73.502355
    }

    override fun onMapReady(googleMap: GoogleMap) {
        this.googleMap = googleMap
        googleMap.setOnCameraMoveListener(this)
    }

    override fun onCameraMove() {
        val cameraPosition = googleMap!!.cameraPosition
        longitude = cameraPosition.target.longitude
        latitude = cameraPosition.target.latitude
        zoom = cameraPosition.zoom
        if (isInArea(latitude, longitude) && !mIsAmapDisplay && mIsAuto) {
            changeToAmapView()
        }
    }

    override fun onLocationChanged(aMapLocation: AMapLocation) {
        if (aMapLocation.errorCode == 0) {
            longitude = aMapLocation.longitude
            latitude = aMapLocation.latitude
            if (aMapLocation.country != "中国") {
                changeToGoogleMapView()
            } else {
                aMap?.moveCamera(
                    CameraUpdateFactory.newLatLngZoom(
                        LatLng(latitude, longitude),
                        15f
                    )
                )
            }
            Toast.makeText(this, aMapLocation.country, Toast.LENGTH_LONG).show()
            mIsAuto = false
            mCheckBtn.isChecked = false
        } else {
            val errText = "定位失败, ${aMapLocation.errorCode}: ${aMapLocation.errorInfo}"
            Log.e("AmapErr", errText)
            Toast.makeText(this, errText, Toast.LENGTH_LONG).show()
        }
    }

    override fun onCheckedChanged(buttonView: CompoundButton, isChecked: Boolean) {
        if (buttonView.id == R.id.auto) {
            mIsAuto = isChecked
        }
    }

    private fun checkGooglePlayServices(): Boolean {
        val result = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this)
        return when (result) {
            ConnectionResult.SUCCESS -> true
            ConnectionResult.SERVICE_VERSION_UPDATE_REQUIRED -> {
                Toast.makeText(this, "SERVICE_VERSION_UPDATE_REQUIRED", Toast.LENGTH_SHORT).show()
                false
            }

            ConnectionResult.SERVICE_INVALID -> {
                AlertDialog.Builder(this)
                    .setMessage("使用谷歌地图，需要安装谷歌相关服务")
                    .setPositiveButton("确定", null)
                    .show()
                false
            }

            ConnectionResult.SERVICE_MISSING -> {
                AlertDialog.Builder(this)
                    .setMessage("使用谷歌地图，需要安装谷歌相关服务")
                    .setPositiveButton("确定", null)
                    .show()
                false
            }

            else -> false
        }
    }

    private fun requestLocationPermission() {
        if (ContextCompat.checkSelfPermission(
                this,
                Manifest.permission.ACCESS_FINE_LOCATION
            ) == PackageManager.PERMISSION_GRANTED &&
            ContextCompat.checkSelfPermission(
                this,
                Manifest.permission.ACCESS_COARSE_LOCATION
            ) == PackageManager.PERMISSION_GRANTED
        ) {
            onLocationPermissionGranted()
        } else {
            ActivityCompat.requestPermissions(
                this,
                arrayOf(
                    Manifest.permission.ACCESS_FINE_LOCATION,
                    Manifest.permission.ACCESS_COARSE_LOCATION
                ),
                1
            )
        }
    }

    override fun onRequestPermissionsResult(
        requestCode: Int,
        @NonNull permissions: Array<String>,
        @NonNull grantResults: IntArray
    ) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults)
        if (requestCode == 1) {
            if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                onLocationPermissionGranted()
            } else {
                onLocationPermissionDenied()
            }
        }
    }

    private fun onLocationPermissionGranted() {
        Toast.makeText(this, "定位权限已开启，可以进行定位操作", Toast.LENGTH_SHORT).show()
    }

    private fun onLocationPermissionDenied() {
        Toast.makeText(this, "定位权限未开启，无法进行定位操作", Toast.LENGTH_SHORT).show()
    }
}